#include "camera.h"


camera::camera(IDirect3DDevice9 *d3ddev, FLOAT fnear, FLOAT ffar)
{
	m_d3ddev = d3ddev;
	m_camPos = D3DXVECTOR3(0.0f, 24.0f, 0.0f);
	m_lookPos = D3DXVECTOR3(1.1f, -0.1f, -0.1f);
	m_up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
	m_speed = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	m_Ymove = false;
	m_pitchlevel = D3DXToRadian(89.0f);


	initProjection(D3DXToRadian(45), (FLOAT)1920 / (FLOAT)1080, 1.f, 1000.0f);
	m_d3ddev->SetTransform(D3DTS_VIEW, &matView);
	D3DXMatrixLookAtLH(&matView, &m_camPos, &m_lookPos, &m_up);

	update();
	
	
}

void camera::initProjection(float fov, float aspect, float nearp, float farp)
{
	m_fov = fov;
	m_aspect = aspect;
	m_near = nearp;
	m_far = farp;

	D3DXMatrixPerspectiveFovLH(&matLook, m_fov, m_aspect, m_near, m_far);
	m_d3ddev->SetTransform(D3DTS_PROJECTION, &matLook);
}

void camera::moveForward(float aspect)
{
	if (m_Ymove)
	{
		m_speed += m_lookPos * aspect;
	}
	else
	{
		D3DXVECTOR3 moveVector(m_lookPos.x, 0.0f, m_lookPos.z);
		D3DXVec3Normalize(&moveVector, &moveVector);
		moveVector *= aspect;
		m_speed += moveVector;
	}
}

void camera::moveLR(float aspect)
{
	m_speed += m_right * aspect;
}

void camera::moveUp(float aspect)
{
	if (m_Ymove)
	{
		m_speed.y += aspect;
	}
}

void camera::update()
{
	if (D3DXVec3Length(&m_speed) > maxspeed)
	{
		m_speed = *(D3DXVec3Normalize(&m_speed, &m_speed)) * maxspeed;
	}

	m_camPos += m_speed;

	m_speed = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	m_lookAtPos = m_camPos + m_lookPos;

	D3DXVECTOR3 up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
	D3DXMatrixLookAtLH(&matView, &m_camPos, &m_lookAtPos, &up);
	m_d3ddev->SetTransform(D3DTS_VIEW, &matView);

	m_right.x = matView._11;
	m_right.y = matView._21;
	m_right.z = matView._31;
	m_up.x = matView._12;
	m_up.y = matView._22;
	m_up.z = matView._32;
	m_lookPos.x = matView._13;
	m_lookPos.y = matView._23;
	m_lookPos.z = matView._33;

	float lookLengthOnXZ = sqrtf(m_lookPos.z * m_lookPos.z + m_lookPos.x * m_lookPos.x);
	m_pitch = atan2f(m_lookPos.y, lookLengthOnXZ);
	m_yaw = atan2f(m_lookPos.x, m_lookPos.z);
}

void camera::pitch(float aspect)
{
	if (aspect == 0.0f)
	{
		return;
	}

	aspect = (m_YPos) ? -aspect : aspect;
	m_pitch -= aspect;
	if (m_pitch > m_pitchlevel)
	{
		aspect += m_pitch - m_pitchlevel;
	}
	else if (m_pitch < -m_pitchlevel)
	{
		aspect += m_pitch + m_pitchlevel;
	}

	D3DXMATRIX rotation;
	D3DXMatrixRotationAxis(&rotation, &m_right, aspect);
	D3DXVec3TransformNormal(&m_up, &m_up, &rotation);
	D3DXVec3TransformNormal(&m_lookPos, &m_lookPos, &rotation);
}

void camera::yaw(float aspect)
{
	if (aspect == 0.0f)
	{
		return;
	}
	D3DXMATRIX rotation;
	D3DXMatrixRotationAxis(&rotation, &m_up, aspect);
	D3DXVec3TransformNormal(&m_right, &m_right, &rotation);
	D3DXVec3TransformNormal(&m_lookPos, &m_lookPos, &rotation);
}

void camera::roll(float aspect)
{
	if (aspect == 0.0f)
	{
		return;
	}
	D3DXMATRIX rotation;
	D3DXMatrixRotationAxis(&rotation, &m_lookPos, aspect);
	D3DXVec3TransformNormal(&m_right, &m_right, &rotation);
	D3DXVec3TransformNormal(&m_up, &m_up, &rotation);
}



camera::~camera()
{
}
